package com.rc.web.controller;




import com.rc.web.service.impl.*;
import com.rc.web.utils.AudioConverter;
import com.rc.web.utils.WavMin;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 有关语言相关的使用的接口
 */
@RestController
@RequestMapping("/LanguageController")
public class LanguageController {

    @Autowired
    private TtsService ttsService;

    @Autowired
    private AsrService asrService;

    @Autowired
    private RerankService rerankService;

    @Autowired
    private AsrDialectService asrDialectService;

    @Autowired
    private AsrVcnService asrVcnService;



    /**
     *文字转语音
     * @param text 要转为语音的文本
     * @return 返回wav的语音文件
     * 使用AI自带的音色需要传入engineid和timbre参数，vcn为0
     * 使用自己复刻的音色需要传入vcn参数，vcn参数为自己复刻的音色的id，engineid和timbre参数可以为空
     */

    @GetMapping("/Voice")
    public ResponseEntity<byte[]> generateAudio(String text,String vcn
            ,String engineid,String timbre) {
        try {
            byte[] wavData = ttsService.generateAudio(text,vcn,engineid,timbre);

            // 将音频文件存储到当前目录
            String fileName = "output_" + System.currentTimeMillis() + ".wav";
            java.nio.file.Path path = java.nio.file.Paths.get(fileName);
            java.nio.file.Files.write(path, wavData);

            return ResponseEntity.ok()
                    .contentType(MediaType.valueOf("audio/wav"))
                    .body(wavData);
        } catch (Exception e) {
            return ResponseEntity.internalServerError().build();
        }
    }


    /**
     * 语音转文字
     * @param audioFile 前端发送的PCM音频文件
     * @return 返回ai语音识别出的文字
     * @throws IOException
     */
    @PostMapping("/writing")
    public ResponseEntity<String> recognizer(@RequestParam("file") MultipartFile audioFile) throws Exception {
        // 读取前端发送的PCM音频数据
        byte[] pcmData = audioFile.getBytes();
        
        // 将PCM转换为WAV格式
        byte[] wavData = AudioConverter.pcmToWav(pcmData);
        
        //解决了前端语音格式不符合vivo要求的问题
        byte[] audioData2 = WavMin.convertAudio(wavData);
        // 将识别的文字返回为字符串格式返回给前端
        String result = asrService.processAudio(audioData2);
        return ResponseEntity.ok(result);
    }

    /**
     * 方言识别
     * @param audioFile 前端发送语音文件
     * @return返回ai语音识别出的文字
     * @throws IOException
     */
    @PostMapping("/dialect")
    public ResponseEntity<String> dialect(@RequestParam("file") MultipartFile audioFile) throws Exception {

        // 读取前端发送的PCM音频数据
        byte[] pcmData = audioFile.getBytes();
        // 将PCM转换为WAV格式
        byte[] wavData = AudioConverter.pcmToWav(pcmData);
        //解决了前端语音格式不符合vivo要求的问题
        byte[] audioData2 = WavMin.convertAudio(wavData);
        //将识别的文字返回为字符串格式返回给前端
        String result = asrDialectService.DialectRecognition(audioData2);
        return ResponseEntity.ok(result);

    }

    /**
     * 声音复刻
     * @param audioFile 前端发送语音文件
     * @return返回ai语音识别出的文字
     */
    @PostMapping("/vcn")
    public String vcn(@RequestParam("file") MultipartFile audioFile) throws Exception {


        //读取前端等待文件为字节
        byte[] audioData = audioFile.getBytes();
        // 将PCM转换为WAV格式
        byte[] wavData = AudioConverter.pcmToWav(audioData);
        //解决了前端语音格式不符合vivo要求的问题
        byte[] audioData2 = WavMin.convertAudio(wavData);
        //识别说话的文字
        String result = asrService.processAudio(audioData2);
        //开始复刻声音
        String result2=asrVcnService.testCreateVcnTask(result,audioData2);


        return result2;

    }

    /**
     * 获取声音复刻的id
     * @return返回ai语音识别出的文字
     */
    @GetMapping("/vcnList")
    public List<Map<String, Object>> vcn() throws Exception {
        //获取复刻的语音列表
        return asrVcnService.testGetVcnTaskList();
    }

    /**
     * 删除所有声音复刻的id
     * @return返回ai语音识别出的文字
     */
    @DeleteMapping ("/vcnList")
    public List<Map<String, Object>> vcn2() throws Exception {
        //获取复刻的语音列表
        asrVcnService.testDeleteAllVcnTasks();
        return asrVcnService.testGetVcnTaskList();
    }

    /**
     * 删除单个声音复刻
     * @param vcn 要删除的VCN ID
     * @return 删除结果
     */
    @DeleteMapping("/vcn/{vcn}")
    public ResponseEntity<Map<String, Object>> deleteSingleVcn(@PathVariable String vcn) {
        Map<String, Object> response = new HashMap<>();
        try {
            boolean result = asrVcnService.testDeleteSingleVcnTask(vcn);
            if (result) {
                response.put("status", "success");
                response.put("message", "VCN deleted successfully");
                return ResponseEntity.ok(response);
            } else {
                response.put("status", "error");
                response.put("message", "Failed to delete VCN");
                return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(response);
            }
        } catch (Exception e) {
            response.put("status", "error");
            response.put("message", e.getMessage());
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(response);
        }
    }



    /**
     * 文本相似度
     * @param requestBody
     * @return
     * @throws IOException
     */
    @PostMapping(value = "/rerank", produces = MediaType.APPLICATION_JSON_VALUE)
    public Map<String, Object> Rerank(@RequestBody Map<String, Object> requestBody) throws Exception {
        String query = (String) requestBody.get("query");
        List<String> sentences = (List<String>) requestBody.get("sentences");

        String[] sentencesArray = sentences.toArray(new String[0]);

        String result = rerankService.rerank(query,sentencesArray);
        System.out.println("返回内容：" + result);

        // 将返回数据封装为JSON格式
        Map<String, Object> response = new HashMap<>();
        response.put("status", "success");
        response.put("data", result);  // 使用data字段更通用
        return response;
    }

}
